package com.lonely.fx.task;

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Task;
import javafx.concurrent.Worker;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.text.NumberFormat;
import java.util.concurrent.CountDownLatch;

/**
 * @date: 2022-08-05 10:29
 * @author: ztkj-hzb
 * @description: Task 基础属性设置
 **/
public class TaskSettingMain extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    boolean isPause = false;

    /**
     * Task生命周期：
     * start--->call--->触发running --执行完毕--> 触发succeeded
     * --执行失败--> 触发failed
     */
    @Override
    public void start(Stage primaryStage) throws Exception {

        HBox hBox = new HBox();

        Button startBtn = new Button("开始");
        Button pauseBtn = new Button("暂停");
        Button cancelBtn = new Button("取消");


        ProgressBar progressBar = new ProgressBar();


        Label progressLbl = new Label("进度值");
        Label statuLbl = new Label("任务状态");
        Label messageLbl = new Label("Message");


        hBox.getChildren().addAll(startBtn, pauseBtn, cancelBtn, progressBar, progressLbl, statuLbl, messageLbl);
        hBox.setAlignment(Pos.CENTER);
        hBox.setSpacing(30);
        primaryStage.setScene(new Scene(hBox));
        primaryStage.setWidth(800);
        primaryStage.setHeight(400);
        primaryStage.show();

        Object object = new Object();
        MyTask myTask = new MyTask(object);
        Thread thread = new Thread(myTask);
        thread.setDaemon(true);

        startBtn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                thread.start();
            }
        });

        cancelBtn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                myTask.cancel();
            }
        });



        pauseBtn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {

                System.out.println(isPause);
                if (isPause) {
                    //
                    pauseBtn.setText("暂停");

                    //执行恢复操作
                    myTask.resume();
                } else {
                    pauseBtn.setText("恢复");

                    //执行暂停操作
                    myTask.pause();
                }

                isPause = !isPause;

            }
        });

        //监听value变化，设置进度值显示
        myTask.valueProperty().addListener(new ChangeListener<Double>() {
            @Override
            public void changed(ObservableValue<? extends Double> observable, Double oldValue, Double newValue) {

                // 保留小数位数
                NumberFormat nf = NumberFormat.getNumberInstance();
                nf.setMaximumFractionDigits(3);
                String result = nf.format(newValue * 100);

                progressLbl.setText(result + "%");
                progressBar.setProgress(newValue);
            }
        });

        //任务消息监听
        myTask.messageProperty().addListener(new ChangeListener<String>() {
            @Override
            public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
                messageLbl.setText(newValue);
            }
        });

        //任务状态监听
        myTask.stateProperty().addListener(new ChangeListener<Worker.State>() {
            @Override
            public void changed(ObservableValue<? extends Worker.State> observable, Worker.State oldValue, Worker.State newValue) {

                statuLbl.setText(newValue.name());

            }
        });
    }
}


class MyTask extends Task<Double> {

    private volatile boolean isPause = false;

    private Object object;

    public MyTask(Object object) {
        this.object = object;
    }

    /**
     * 暂停线程
     *
     * @return
     */
    public void pause() {
        isPause = true;
    }


    /**
     * 暂停线程
     *
     * @return
     */
    public void resume() {
        isPause = false;
        synchronized (object){
            object.notifyAll();
        }
    }


    /**
     * 调用线程--复制一张图片
     */
    @Override
    protected Double call() throws Exception {
        //System.out.println("MyTask:" + Thread.currentThread().getName());
        //System.out.println(1/0);

        InputStream resourceAsStream = this.getClass().getResourceAsStream("/icons/sc01.png");
        int total = resourceAsStream.available();

        FileOutputStream fileOutputStream = new FileOutputStream(new File("D:/test.png"));

        double sum = 0;

        byte[] bytes = new byte[50];
        int readCount;

        double currentPropress = 0.0;
        while ((readCount = resourceAsStream.read(bytes)) != -1) {

            synchronized (object) {

                if (this.isCancelled()) {
                    break;
                }

                if (isPause) {
                    object.wait();
                }

                fileOutputStream.write(bytes, 0, readCount);
                sum += readCount;

                //回写进度
                currentPropress = sum / total;
                this.updateValue(currentPropress);

                Thread.sleep(50);
            }
        }

        fileOutputStream.close();
        resourceAsStream.close();

        return currentPropress;
    }

    /**
     * task运行时触发
     */
    @Override
    protected void running() {
        super.running();
        System.out.println("running");

        //获取message值
        System.out.println(this.getMessage());
        //获取当前线程状态
        System.out.println(this.getState());


    }

    /**
     * task运行成功时触发
     *
     * @since JavaFX 2.1
     */
    @Override
    protected void succeeded() {
        super.succeeded();

        //获取task执行完毕后的返回值
        System.out.println("succeeded,result value:" + this.getValue());
    }

    /**
     * 取消task时触发
     */
    @Override
    protected void cancelled() {
        super.cancelled();
        System.out.println("cancelled");

        //更新messagae
        this.updateMessage("已取消");
    }

    /**
     * task执行失败触发
     */
    @Override
    protected void failed() {
        super.failed();

        //异常时候获取异常对象
        Throwable exception = this.getException();

        System.out.println("failed，reason:" + exception.getMessage());
    }

    /**
     *
     */
    @Override
    protected void updateProgress(long workDone, long max) {
        super.updateProgress(workDone, max);
        System.out.println("updateProgress: " + workDone + "-" + max);
    }

    /**
     *
     */
    @Override
    protected void updateMessage(String message) {
        super.updateMessage(message);
        System.out.println("updateMessage:" + message);
    }

    /**
     *
     */
    @Override
    protected void updateTitle(String title) {
        super.updateTitle(title);
        System.out.println("updateTitle:" + title);
    }

    /**
     * 更新值
     */
    @Override
    protected void updateValue(Double value) {
        super.updateValue(value);
        System.out.println("updateValue:" + value);

        if (value >= 0.5 && value < 0.8) {
            this.updateMessage("任务执行过半");
        } else if (value >= 0.8 && value < 1.0) {
            this.updateMessage("即将结束");
        } else if (value >= 1) {
            this.updateMessage("执行完毕");
        } else {
            this.updateMessage("进行中");
        }

    }
}